#pragma once
#include "Common.hpp"
#include "InterAddr.hpp"
// 要实现echo
class TcpServer : public NoCopy
{
public:
    TcpServer(uint16_t port)
        : _listensockfd(-1),
          _port(port),
          _running(0)
    {
    }
    void Init()
    {

        // 创建套接字
        _listensockfd = socket(AF_INET, SOCK_STREAM, 0); // tcp socket
        if (_listensockfd < 0)
        {
            perror("create listeansocket fail");
            exit(ExitCode::SOCKET_FAIL);
        }
        std::cout << "socket success " << _listensockfd << std::endl;
        // 绑定套接字
        InterAddr addr(_port);
        int n = bind(_listensockfd, addr.NetAddrPtr(), addr.NetAddrLen());
        if (n < 0)
        {
            perror("bind fail");
            exit(ExitCode::BIND_FAIL);
        }
        std::cout << "bind success " << _listensockfd << std::endl;
        // 将套接字变成listen的
        int m = listen(_listensockfd, 8);
        if (m < 0)
        {
            perror("listen fail");
            exit(ExitCode::LISTEN_FAIL);
        }
        std::cout << "listen success " << _listensockfd << std::endl;
    }
    void Server(int sockfd, InterAddr &peer)
    {
        char buffer[1024];
        while (1)
        {
            // 先收到消息
            int n = read(sockfd, buffer, sizeof(buffer) - 1);
            if (n > 0)
            {
                buffer[n] = 0;
              //  std::cout<<"可以看见吗"<<std::endl;
                std::cout << "client say@#" << buffer<<std::endl;
                std::string echo_string = "client say#@";
                echo_string += buffer;
                // 进行发送
                write(sockfd, echo_string.c_str(), echo_string.size());
            }
            else if (n < 0)
            {
                perror("read fail");
                exit(ExitCode::READ_FAIL);
            }
            else
            {
                printf("读取结束\n");
                exit(ExitCode::OK);
            }
        }
    }

    void Run()
    {
        _running = true;
        while (1)
        {
            // 建立链接
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            int sockfd = accept(_listensockfd, CONV(peer), &len);
            if (sockfd < 0)
            {
                perror("accept fail");
                exit(ExitCode::ACCEPT_FAIL);
            }
            std::cout << "accept success" << std::endl;
            // 可以进行服务了；
            InterAddr addr(peer);
            Server(sockfd, addr);
        }
    }
    ~TcpServer() {}

private:
    int _listensockfd;
    uint16_t _port;
    bool _running;
};
